Java中对对象的集合或数组进行排序时通常有两种方式:Comparator && Comparable。
Comparable要求使用对象实现其compareTo方法来实现自定义的排序方式。
但在使用的场景中,往往在设计时并没有考虑到比较问题从而没有实现Comparable,这时候再去改造对象本身或许不太合适。
Comparator更加的灵活,采用的是策略模式,在不改变对象本身的情况下来改变对象的行为
举例说明:
class User {
//年龄
private Integer age;
//身高
private Integer height;
//姓名
private String name;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
现在需要给所有的User对象按年龄从小到大排序,如果年龄相同则按身高由高到低来排序。
以下是Comparable方式,通过改造User对象来实现自定义compileTo方法:
class User implements Comparable<User>{
//年龄
private Integer age;
//身高
private Integer height;
//姓名
private String name;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(User u) {
int flag = this.age.compareTo(u.getAge());
if (flag == 0 ) {
return (this.height.compareTo(u.getHeight())) * -1;
} else {
return flag;
}
}
}
以下是Comparator的实现方法及测试类:
public class Test {
public static void main(String[] args) {
User user1 = new User();
user1.setAge(20);
user1.setHeight(180);
user1.setName("张三");
User user2 = new User();
user2.setAge(20);
user2.setHeight(176);
user2.setName("李四");
User user3 = new User();
user3.setAge(25);
user3.setHeight(155);
user3.setName("王二");
User user4 = new User();
user4.setAge(23);
user4.setHeight(155);
user4.setName("麻子");
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
//使用Comparator实现排序
Collections.sort(userList, new Comparator<User>() {
@Override
public int compare(User u1, User u2) {
int flag = u1.getAge().compareTo(u2.getAge());
if (flag == 0) {
//身高降序
return (u1.getHeight().compareTo(u2.getHeight())) * -1;
} else {
return flag;
}
}
});
//如果使用Comparable方式,可直接使用以下方式排序即可
Collections.sort(userList);
for (User u : userList) {
System.out.println("姓名:"+u.getName()+",年龄:"+u.getAge()+",身高:"+u.getHeight());
}
}
}
结果:
姓名:张三,年龄:20,身高:180
姓名:李四,年龄:20,身高:176
姓名:麻子,年龄:23,身高:155
姓名:王二,年龄:25,身高:155
达到的效果一致,但是,这并没有结束。
在Java规范里,倡导保证equals和compareTo的行为一致,这样可以避免出现一些奇奇怪怪的问题。大致意思就是如果user1.compareTo(user2) == 0 的话,user1.equals(user2) == 1
既然重载了equals,那意味着hashcode也得重载了~ 你懂的